#!/bin/bash

# 生产环境紧急修复脚本
# 解决MySQL端口访问和Nginx配置问题
# 使用方法: chmod +x emergency-production-fix.sh && ./emergency-production-fix.sh

echo "🚨 开始生产环境紧急修复..."
echo "服务器: 47.237.10.129"
echo "时间: $(date)"
echo "========================================"

# 配置变量
SERVER_IP="47.237.10.129"
SERVER_USER="root"
APP_PORT="3000"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查本地环境
check_local_environment() {
    log_info "检查本地环境..."
    
    # 检查SSH连接
    if ! ssh -o ConnectTimeout=10 $SERVER_USER@$SERVER_IP "echo 'SSH连接正常'" 2>/dev/null; then
        log_error "无法连接到服务器 $SERVER_IP"
        log_error "请检查:"
        echo "  1. 服务器IP是否正确"
        echo "  2. SSH密钥是否配置正确"
        echo "  3. 服务器是否正在运行"
        exit 1
    fi
    
    log_info "✅ SSH连接正常"
}

# 创建修复后的Nginx配置
create_nginx_config() {
    log_info "创建修复后的Nginx配置..."
    
    cat > nginx-production-emergency-fix.conf << 'EOF'
# 紧急修复后的生产环境Nginx配置
# 部署位置: /etc/nginx/conf.d/cu-mr-bull.conf

# 上游服务器配置 - 修复upstream地址
upstream cu_mr_bull_api {
    server 127.0.0.1:3000 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

# 限流设置
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;

# HTTP重定向 - API域名
server {
    listen 80;
    server_name api.cumrbull.com.sg;
    
    # Let's Encrypt验证
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    
    # 重定向到HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

# HTTP重定向 - 管理后台域名
server {
    listen 80;
    server_name admin.cumrbull.com.sg;
    
    # Let's Encrypt验证
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    
    # 重定向到HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

# HTTPS服务器 - 主API服务
server {
    listen 443 ssl http2;
    server_name api.cumrbull.com.sg;
    
    # SSL配置
    ssl_certificate /etc/letsencrypt/live/api.cumrbull.com.sg/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.cumrbull.com.sg/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    
    # HSTS
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    
    # 日志
    access_log /var/log/nginx/api.cumrbull.access.log;
    error_log /var/log/nginx/api.cumrbull.error.log;
    
    # 健康检查 - 无限流
    location /health {
        proxy_pass http://cu_mr_bull_api/health;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 5s;
        proxy_send_timeout 10s;
        proxy_read_timeout 10s;
    }
    
    # 登录接口 - 严格限流
    location ~ ^/api/(auth/login|auth/register) {
        limit_req zone=login burst=3 nodelay;
        
        proxy_pass http://cu_mr_bull_api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 10s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
    
    # 一般API接口 - 标准限流
    location /api/ {
        limit_req zone=api burst=10 nodelay;
        
        proxy_pass http://cu_mr_bull_api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 10s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
    
    # 根路径 - API信息
    location / {
        proxy_pass http://cu_mr_bull_api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    
    # 静态文件服务
    location /uploads/ {
        alias /opt/cumbull/backend/uploads/;
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header X-Content-Type-Options nosniff;
    }
}

# HTTPS服务器 - 管理后台
server {
    listen 443 ssl http2;
    server_name admin.cumrbull.com.sg;
    
    # SSL配置（与主域名相同）
    ssl_certificate /etc/letsencrypt/live/api.cumrbull.com.sg/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.cumrbull.com.sg/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    
    # 日志
    access_log /var/log/nginx/admin.cumrbull.access.log;
    error_log /var/log/nginx/admin.cumrbull.error.log;
    
    # 管理后台API路由 - 直接代理，不重定向
    location /api/ {
        proxy_pass http://cu_mr_bull_api/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
    
    # 静态文件服务（管理界面）
    location / {
        root /var/www/admin;
        index index.html;
        try_files $uri $uri/ /index.html;
        
        # 如果没有静态文件，临时重定向到API健康检查
        error_page 404 = @fallback;
    }
    
    location @fallback {
        return 302 /api/health;
    }
}
EOF

    log_info "✅ Nginx配置文件已创建"
}

# 创建生产环境变量修复文件
create_production_env() {
    log_info "创建修复后的生产环境变量..."
    
    cat > .env.production.fixed << 'EOF'
# 修复后的生产环境配置
# 阿里云RDS MySQL数据库配置
DB_HOST=rm-t4n2um727ltmubz.mysql.singapore.rds.aliyuncs.com
DB_PORT=3306
DB_USER=cmb_admin
DB_PASSWORD=132Singer45#$
DB_NAME=cumrbull

# 服务器配置
PORT=3000
NODE_ENV=production
APP_ENV=production

# JWT配置 - 使用强随机密钥
JWT_SECRET=prod_jwt_$(openssl rand -hex 32)
JWT_REFRESH_SECRET=prod_refresh_$(openssl rand -hex 32)
JWT_EXPIRES_IN=24h
JWT_REFRESH_EXPIRES_IN=7d

# 域名配置
API_BASE_URL=https://api.cumrbull.com.sg
FRONTEND_URL=https://cumrbull.com.sg
ADMIN_URL=https://admin.cumrbull.com.sg

# CORS配置
CORS_ORIGIN=https://admin.cumrbull.com.sg,https://cumrbull.com.sg

# 安全配置
ENCRYPTION_KEY=prod_encryption_$(openssl rand -hex 16)
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
BCRYPT_SALT_ROUNDS=12

# 文件上传配置
UPLOAD_PATH=./uploads
MAX_FILE_SIZE=10485760

# 邮件配置
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=admin@cumrbull.com.sg
EMAIL_PASS=your-app-password
EMAIL_FROM=noreply@cumrbull.com.sg

# Redis配置
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=

# 日志配置
LOG_LEVEL=info
LOG_FILE=./logs/production.log
EOF

    log_info "✅ 生产环境变量文件已创建"
}

# 部署修复到服务器
deploy_fixes() {
    log_info "部署修复到服务器..."
    
    # 1. 备份现有配置
    log_info "备份现有配置..."
    ssh $SERVER_USER@$SERVER_IP << 'EOF'
# 创建备份目录
mkdir -p /root/backup/$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/root/backup/$(date +%Y%m%d_%H%M%S)"

# 备份Nginx配置
cp /etc/nginx/conf.d/cu-mr-bull.conf $BACKUP_DIR/ 2>/dev/null || echo "Nginx配置文件不存在"

# 备份环境变量
cp /opt/cumbull/backend/.env.production $BACKUP_DIR/ 2>/dev/null || echo "环境变量文件不存在"

echo "✅ 配置已备份到 $BACKUP_DIR"
EOF

    # 2. 上传新配置
    log_info "上传新配置文件..."
    scp nginx-production-emergency-fix.conf $SERVER_USER@$SERVER_IP:/etc/nginx/conf.d/cu-mr-bull.conf
    scp .env.production.fixed $SERVER_USER@$SERVER_IP:/opt/cumbull/backend/.env.production
    
    # 3. 在服务器上执行修复
    log_info "在服务器上执行修复..."
    ssh $SERVER_USER@$SERVER_IP << 'EOF'
echo "🔧 开始服务器端修复..."

# 进入后端目录
cd /opt/cumbull/backend

# 创建必要目录
mkdir -p logs uploads

# 停止现有Node.js进程
echo "停止现有服务..."
pkill -f "node.*production-server.js" || echo "没有运行的Node.js进程"
pkill -f "node.*start-server.js" || echo "没有运行的start-server进程"
sleep 2

# 检查并安装PM2（如果没有）
if ! command -v pm2 &> /dev/null; then
    echo "安装PM2..."
    npm install -g pm2
fi

# 启动应用服务
echo "启动应用服务..."
if [ -f "production-server.js" ]; then
    pm2 start production-server.js --name "cumrbull-api" --env production
elif [ -f "start-server.js" ]; then
    pm2 start start-server.js --name "cumrbull-api" --env production
else
    echo "❌ 找不到启动文件"
    exit 1
fi

# 保存PM2配置
pm2 save
pm2 startup

echo "等待服务启动..."
sleep 5

# 测试Nginx配置
echo "测试Nginx配置..."
nginx -t
if [ $? -eq 0 ]; then
    echo "✅ Nginx配置语法正确"
    systemctl reload nginx
    echo "✅ Nginx已重新加载"
else
    echo "❌ Nginx配置语法错误"
    exit 1
fi

# 检查服务状态
echo "\n📊 检查服务状态..."
echo "PM2进程状态:"
pm2 status

echo "\n端口监听状态:"
netstat -tlnp | grep -E ':(80|443|3000)'

echo "\n测试本地健康检查:"
curl -s http://localhost:3000/health || echo "本地健康检查失败"

echo "\n✅ 服务器端修复完成"
EOF

    log_info "✅ 服务器修复完成"
}

# 验证修复结果
verify_fixes() {
    log_info "验证修复结果..."
    
    echo "\n🧪 测试连接..."
    
    # 测试健康检查
    echo "测试API健康检查:"
    if curl -s -m 10 https://api.cumrbull.com.sg/health; then
        log_info "✅ API健康检查正常"
    else
        log_warn "⚠️ API健康检查失败"
    fi
    
    echo "\n测试管理后台API:"
    if curl -s -m 10 https://admin.cumrbull.com.sg/api/health; then
        log_info "✅ 管理后台API正常"
    else
        log_warn "⚠️ 管理后台API失败"
    fi
    
    # 测试数据库连接（从服务器）
    echo "\n测试数据库连接:"
    ssh $SERVER_USER@$SERVER_IP << 'EOF'
cd /opt/cumbull/backend
node -e "
const mysql = require('mysql2/promise');
require('dotenv').config();
(async () => {
  try {
    const conn = await mysql.createConnection({
      host: process.env.DB_HOST,
      port: process.env.DB_PORT,
      user: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_NAME
    });
    console.log('✅ 数据库连接成功');
    await conn.end();
  } catch (e) {
    console.log('❌ 数据库连接失败:', e.message);
  }
})();
" 2>/dev/null || echo "❌ 数据库连接测试失败"
EOF
}

# 生成修复报告
generate_report() {
    log_info "生成修复报告..."
    
    cat > emergency-fix-report.md << EOF
# 生产环境紧急修复报告

**修复时间**: $(date)  
**服务器**: 47.237.10.129  
**执行人**: $(whoami)

## 修复内容

### ✅ 已完成的修复
1. **Nginx配置修复**
   - 修正upstream服务器地址: app:3000 → 127.0.0.1:3000
   - 添加API限流保护
   - 修复代理配置和HTTP头设置
   - 优化SSL/TLS配置

2. **环境变量优化**
   - 更新JWT密钥为强随机值
   - 完善CORS配置
   - 添加安全配置项
   - 优化日志和上传配置

3. **服务管理改进**
   - 使用PM2进行进程管理
   - 配置自动重启
   - 添加健康检查

### ⚠️ 仍需解决的问题
1. **MySQL端口3306访问**
   - 需要在阿里云安全组中开放3306端口
   - 建议仅允许应用服务器IP访问

2. **Staging环境创建**
   - 需要配置独立的测试环境
   - 参考staging-environment-setup.sh脚本

## 验证结果

- API健康检查: https://api.cumrbull.com.sg/health
- 管理后台API: https://admin.cumrbull.com.sg/api/health
- 数据库连接: 需要开放端口后测试

## 后续行动

1. **立即执行**:
   - 在阿里云控制台开放MySQL端口3306
   - 测试数据库连接
   - 验证所有API端点

2. **本周内完成**:
   - 创建Staging环境
   - 配置监控和告警
   - 完善备份策略

## 回滚方案

如果出现问题，可以使用备份的配置文件快速回滚：
\`\`\`bash
# 在服务器上执行
cp /root/backup/\$(ls -t /root/backup/ | head -1)/cu-mr-bull.conf /etc/nginx/conf.d/
nginx -t && systemctl reload nginx
\`\`\`

---
**修复状态**: ✅ 基础修复完成，等待端口开放验证
EOF

    log_info "✅ 修复报告已生成: emergency-fix-report.md"
}

# 主执行流程
main() {
    echo "🚨 生产环境紧急修复开始"
    echo "========================================"
    
    check_local_environment
    create_nginx_config
    create_production_env
    deploy_fixes
    verify_fixes
    generate_report
    
    echo "\n🎉 紧急修复完成！"
    echo "========================================"
    echo "📋 后续步骤:"
    echo "1. 在阿里云控制台开放MySQL端口3306"
    echo "2. 验证API端点: https://api.cumrbull.com.sg/health"
    echo "3. 测试管理后台: https://admin.cumrbull.com.sg"
    echo "4. 查看修复报告: emergency-fix-report.md"
    echo "5. 创建Staging环境: ./staging-environment-setup.sh"
    echo ""
    echo "🆘 如有问题，请查看备份目录: /root/backup/"
}

# 执行主流程
main "$@"